package com.ybkj.daijia.api.apirest;

import com.ybkj.daijia.serverUtils.RegExpValidatorUtils;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.api.member.ErrorConstant;
import com.ybkj.daijia.api.member.transport.ResultTransport;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.config.PassengerApi;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.server.event.DriverRebateEvent;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.mc.PassengerAddress;
import com.ybkj.daijia.server.mc.PassengerConcats;
import com.ybkj.daijia.server.mc.PassengerGrade;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.MemberRebate;
import com.ybkj.daijia.server.reactor.ReactorVo;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.DriverService;
import com.ybkj.daijia.server.service.ErrandService;
import com.ybkj.daijia.server.service.FreightService;
import com.ybkj.daijia.server.service.MemberRebateService;
import com.ybkj.daijia.server.service.MemberService;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;

@Controller("ApiPassengerProcessController")
@RequestMapping(value = "api/passenger/")
public class PassengerProcessController {

    private static final Logger logger = LoggerFactory.getLogger(PassengerProcessController.class);
    @Autowired
    FreightService freightService;
    @Autowired
    private SettingUtils settingUtils;
    @Autowired
    private MemberService memberService;
    @Autowired
    private ErrandService errandService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private DriverService driverService;
    @Autowired
    private MemberRebateService memberRebateService;
    @Autowired
    private PassengerApi passengerApi;
    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    public static void main(String[] args) {
        String str = "17381823824";
        System.out.println(RegExpValidatorUtils.isPhone(str));
    }

    @RequestMapping("getQrCodeData")
    public @ResponseBody
    Map<String, Object> getQrCodeData(Long passengerId, String acKey) {

        Map<String, Object> map = new HashMap<String, Object>();

        String shareUrl = "member/api/rest/v3/shareQrCode/" + passengerId + "";

        Company company = null;
        String qrLogo = null;
        Passenger passenger = memberService.findOnePassenger(passengerId);

        if (StringUtils.isNotBlank(acKey)) {
            company = companyService.findByAppKey(acKey);
            if (null != company) {
                shareUrl += "?cid=" + company.getId() + "";
            }
        }
        if (null == company && null != passenger) {
            company = companyService.findOne(passenger.getCompanyId());
        }
        if (null == company) {
            company = companyService.findOne(passenger.getCompanyId());
        }

        qrLogo = company.getLogo();

        map.put("shareUrl", shareUrl);
        map.put("qrLogo", qrLogo);

        MemberRebate memberRebate = memberRebateService.findByCompany(company.getId());
        if (null != memberRebate) {
            map.put("description", memberRebate.getContent());
        } else {
            map.put("description", "");
        }
        map.put("shareTitle", company.getIntroduceTitle());
        map.put("shareContent", company.getIntroduceContent());

        map.put("success", true);

        return map;
    }

    /**
     * 获取用户的紧急联系人和常用目的地
     *
     * @param passengerId 客户Id
     * @param appKey      系统Key
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "getPassengerEcnEcpAndAddress", method = {RequestMethod.GET})
    public Map<String, Object> getPassengerEcnEcpAndAddress(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "appKey") String appKey) {

        Map<String, Object> returnMap = new HashMap<String, Object>();
        Map<String, Object> dataMap = new HashMap<String, Object>();

        try {
            List<PassengerConcats> concats = errandService.findPassengerConcats(passengerId);
            PassengerConcats passengerConcats = null;
            if (!CollectionUtils.isEmpty(concats)) {
                passengerConcats = concats.get(0);
            }
            if (null != passengerConcats) {
                dataMap.put("memberEcn", passengerConcats.getName());
                dataMap.put("memberEcp", passengerConcats.getPhone());
            } else {
                dataMap.put("memberEcn", null);
                dataMap.put("memberEcp", null);
            }

            PassengerAddress passengerAddress = errandService
                .findPassengerToPlace(passengerId, PassengerAddress.TYPE_ADDRESS_OTHER);
            if (null != passengerAddress) {
                dataMap.put("memberUsual", passengerAddress.getAddress());
                dataMap.put("lat", passengerAddress.getLatitude());
                dataMap.put("lng", passengerAddress.getLongitude());
            } else {
                dataMap.put("memberUsual", null);
                dataMap.put("lat", null);
                dataMap.put("lng", null);
            }
            returnMap.put("success", true);
            returnMap.put("data", dataMap);
            returnMap.put("message", "ok");
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", false);
            returnMap.put("data", null);
            returnMap.put("message", "系统异常");
        }
        return returnMap;
    }

    /**
     * 微信公众号V5版本更新乘客信息
     *
     * @param phone     电话
     * @param appKey    系统Key
     * @param name      姓名
     * @param gender    性别
     * @param memberEcn 紧急联系人姓名
     * @param memberEcp 紧急联系人电话
     * @param address   常用目的地
     * @param lat       常用目的地lat
     * @param lng       常用目的地lng
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "wxV5updatePassenger", method = {RequestMethod.POST})
    public Map<String, Object> updatePassengerInfo(
        @RequestParam(value = "phone", required = true) String phone,
        @RequestParam(value = "appKey", required = true) String appKey,
        @RequestParam(value = "name", required = false) String name,
        @RequestParam(value = "gender", required = false) Integer gender,
        @RequestParam(value = "memberEcn", required = false) String memberEcn,
        @RequestParam(value = "memberEcp", required = false) String memberEcp,
        @RequestParam(value = "address", required = false) String address,
        @RequestParam(value = "lat", required = false) Double lat,
        @RequestParam(value = "lng", required = false) Double lng) {

        Map<String, Object> returnMap = new HashMap<String, Object>();

        try {
            // 判断有无更新信息
            if (null == name && null == gender && null == memberEcn && null == memberEcp
                && null == address && null == lat && null == lng) {
                returnMap.put("success", false);
                returnMap.put("errorMsg", "请传入要更新的用户数据");
                return returnMap;
            }

            // 有要更新的数据，获取用户信息，开始更新
            Passenger passenger = memberService.findOnePassengerByPhone(phone);
            if (null == passenger) {
                returnMap.put("success", false);
                returnMap.put("errorMsg", "未获取乘客信息");
                return returnMap;
            }

            // 姓名，性别不为空时，更新用户姓名性别
            if ((null != name && !name.isEmpty()) || (null != gender)) {

                if (null != name && !name.isEmpty()) {
                    passenger.setName(name);
                }
                if (null != gender) {
                    passenger.setGender(gender);
                }

                Result<Passenger> passen = memberService.updatePassenger(passenger);
                if (!passen.isSuccess()) {
                    returnMap.put("success", false);
                    returnMap.put("errorMsg", "更新乘客姓名，性别失败 -- " + passen.getMessage());
                    return returnMap;
                }
            }

            // 紧急联系人不为空时，更新紧急联系人
            if ((null != memberEcn && !memberEcn.isEmpty()) || (null != memberEcp && !memberEcp
                .isEmpty())) {

                if (null != memberEcn && !memberEcn.isEmpty()) {
                    passenger.setMemberEcn(memberEcn);
                }
                if (null != memberEcp && !memberEcp.isEmpty()) {
                    passenger.setMemberEcp(memberEcp);
                }

                Result<PassengerConcats> concats = memberService
                    .updateEcnEcp(passenger, memberEcn, memberEcp);
                if (!concats.isSuccess()) {
                    returnMap.put("success", false);
                    returnMap.put("errorMsg", "更新紧急联系人失败 -- " + concats.getMessage());
                    return returnMap;
                }
            }

            // 常用目的地不为空时，更新常用目的地
            if (null != address && !address.isEmpty() && null != lat && null != lng) {
                passenger.setAddress(address);
                passenger.setLatitude(lat);
                passenger.setLongitude(lng);

                Result<PassengerAddress> result = memberService
                    .updateUsuallyAddress(passenger.getId(), address, lat, lng,
                        PassengerAddress.TYPE_ADDRESS_OTHER);
                if (!result.isSuccess()) {
                    returnMap.put("success", false);
                    returnMap.put("errorMsg", "更新常用地址失败 -- " + result.getMessage());
                    return returnMap;
                }
            }

            returnMap.put("success", true);
            returnMap.put("errorMsg", "更新成功");
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", false);
            returnMap.put("errorMsg", "更新异常");
        }
        return returnMap;
    }

    /**
     * 客户上传头像
     *
     * @param req
     * @param photoFile 头像文件
     * @param phone     电话
     * @param appKey    系统key
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "uploadPhoto", method = {RequestMethod.POST})
    public ResultTransport uploadPhoto(
        HttpServletRequest req,
        @RequestParam(required = true, value = "photoFile") MultipartFile photoFile,
        @RequestParam(required = true, value = "phone") String phone,
        @RequestParam(required = true, value = "appKey") String appKey) {

        logger.debug("recv phone:{},appKey:{},token:{},timestamp:{}", phone, appKey);

        if (StringUtils.isBlank(phone)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        try {
            Passenger passenger = memberService.findOnePassengerByPhone(phone);
            if (null == passenger) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }
            try {
                String bathPath = WebUtils.getRealPath(req.getSession().getServletContext(), "/");
                File dir = new File(bathPath, "upload/member");
                FileUtils.forceMkdir(dir);
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
                String fileName = String
                    .format("%s.png", df.format(new Date()) + "_" + new Random().nextInt(1000));
                byte[] data = photoFile.getBytes();
                FileOutputStream out = new FileOutputStream(new File(dir, fileName));
                IOUtils.write(data, out);
                IOUtils.closeQuietly(out);
                passenger.setPhoto(fileName);
            } catch (Exception e) {
                e.printStackTrace();
                logger.debug(e.getMessage());
            }
            memberService.updatePassenger(passenger);
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
            instance.setData(null);
            return instance;
        } catch (Exception e) {
            logger.error("api v3 member uploadPhoto error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }
    }

    /**
     * 根据客户查询其推荐返利
     *
     * @param passengerId 客户id
     * @param payType     支付类型
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "getRecommendRebateByPassenger", method = {RequestMethod.GET})
    public Map<String, Object> getRecommendRebateByPassenger(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "payType") String payType,
        @RequestParam(required = true, value = "page") Integer page,
        @RequestParam(required = true, value = "rows") Integer rows) {

        // 数据容器
        Map<String, Object> returnMap = new LinkedHashMap<String, Object>();
        List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();

        try {
            // 获取该用户
            Result<Passenger> result = passengerApi
                .findOnePassenger(passengerId, settingUtils.get());
            Passenger passenger = result.getResult();

            // 获取该用户的每个推荐人
            Page<Map<String, Object>> data = memberService
                .queryByIntroducer(passenger.getPhone(), Passenger.INTRODUCE_TYPE_PASSENGER, page,
                    rows);

            // 获取用户从每个推荐人获取的返利总和
            List<Map<String, Object>> list = data.getContent();
            for (Map<String, Object> map : list) {

                Long introducerId = Long.parseLong(String.valueOf(map.get("id"))); // 被推荐人ID
                String introducerPhone = String.valueOf(map.get("phone")); // 被推荐人电话
                String introducerDate = String.valueOf(map.get("date")); // 被推荐时间

                // 获取这位被推荐人对这位推荐者的返利总和
                BigDecimal sumMoney = passengerApi.sumPassengerAccountMoney(null, passengerId,
                    introducerId, null, null, null, payType, null, settingUtils.get());

                // 处理电话
                int len = introducerPhone.length();
                if (len >= 11) {
                    String fix = introducerPhone.substring(len - 4, len);
                    String fre = introducerPhone.substring(0, len - 8);
                    introducerPhone = fre + "****" + fix;
                }

                // 加入列表单元
                Map<String, Object> dataMap = new LinkedHashMap<String, Object>();
                dataMap.put("introducerPhone", introducerPhone);
                dataMap.put("introducerDate", introducerDate.replaceAll("-", "."));
                dataMap.put("sumMoney", sumMoney);

                // 列表单元入列表
                listMap.add(dataMap);
            }

            // 加入返回Map返回数据
            returnMap.put("success", true);
            returnMap.put("message", "ok");
            returnMap.put("content", listMap);
            returnMap.put("size", data.getSize());
            returnMap.put("sort", data.getSort());
            returnMap.put("numberOfElements", data.getNumberOfElements());
            returnMap.put("number", data.getNumber());
            returnMap.put("totalPages", data.getTotalPages());
            returnMap.put("totalElements", data.getTotalElements());
            returnMap.put("totalPages", data.getTotalPages());
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", false);
            returnMap.put("message", "system exception ==> " + e.getMessage());
        }
        return returnMap;
    }

    /**
     * 查询货运的今日下单量
     *
     * @param passengerId 客户id
     * @param appKey      系统key
     * @return false 表示下单量达到今日最大
     */
    @ResponseBody
    @RequestMapping(value = "getCreateOrderNumberFreight", method = {RequestMethod.GET})
    public boolean getCreateOrderNumberFreight(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "appKey") String appKey) {
        try {
            // 货运每日的下单量
            Long freightOrder = freightService.getCreateOrderNumber(passengerId, appKey);
            // 查询客户信息
            Passenger OneGradeId = memberService.findOnePassenger(passengerId);
            if (null == OneGradeId.getGrade_id()) {
                return true;
            }
            // 根据客户信息查询等级id
            PassengerGrade passengerGrade = memberService.findOneGrade(OneGradeId.getGrade_id());
            // 根据等级id查询每日最大下单量
            Integer dailyOrders = passengerGrade.getDailyOrders();
            // dailyOrders=null,表示不限制
            if (null == dailyOrders || dailyOrders == 0) {
                return true;
            }
            if (freightOrder.longValue() >= dailyOrders.intValue()) {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }
        return true;
    }

    /**
     * 查询跑腿的今日下单量
     *
     * @param passengerId 客户id
     * @param appKey      系统key
     * @return false 表示下单量达到今日最大
     */
    @ResponseBody
    @RequestMapping(value = "getCreateOrderNumberErrand", method = {RequestMethod.GET})
    public boolean getCreateOrderNumberErrand(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "appKey") String appKey) {
        try {
            // 跑腿每日的下单量
            Long errandOrder = errandService.getCreateOrderNumber(passengerId, appKey);

            // 查询客户信息
            Passenger OneGradeId = memberService.findOnePassenger(passengerId);
            if (null == OneGradeId.getGrade_id()) {
                return true;
            }
            // 根据客户信息查询等级id
            PassengerGrade passengerGrade = memberService.findOneGrade(OneGradeId.getGrade_id());
            // 根据等级id查询每日最大下单量
            Integer dailyOrders = passengerGrade.getDailyOrders();
            // dailyOrders=null,表示不限制
            if (null == dailyOrders || dailyOrders == 0) {
                return true;
            }
            if (errandOrder.longValue() >= dailyOrders.intValue()) {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }
        return true;
    }

    @RequestMapping(path = "bindOrCreatePassengerForWeixinIntroduce", method = RequestMethod.POST)
    public ResponseEntity<Result> bindOrCreatePassengerForWeixinIntroduce(@RequestBody Passenger pa,
        @RequestParam(required = false, value = "driverId") Long driverId,
        @RequestParam("appKey") String appKey,
        @RequestParam(value = "update", required = false) Boolean update) {
        ResponseEntity<Result> entity = null;
        Result<Passenger> res = new Result();
//        Passenger pa = new Passenger();
        if (!RegExpValidatorUtils.isPhone(pa.getPhone())) {
            res.setSuccess(false);
            res.setMessage("没有手机");
            entity = new ResponseEntity<Result>(res, HttpStatus.INTERNAL_SERVER_ERROR);
            return entity;
        }
//        pa.setPhone(phone);
//        pa.setName(name);
//        pa.setCompanyId(companyId);
//        pa.setCompanyName(companyName);
//        pa.setChannel_name(channelName);
        Driver one = null;
        if (null != driverId) {
            one = driverService.findOne(driverId);
            if (null != one) {
                pa.setIntroducer(one.getUsername());
                pa.setIntroduceType(Passenger.INTRODUCE_TYPE_DRIVER);
                pa.setChannel_name(Passenger.PASSENGER_CHANNEL_INVITE);
            }
        }
        if (null == update || !update) {
            res = passengerApi.createPersonal(pa, settingUtils.get());
        } else {
            Map<String, Object> map = passengerApi.updateChannel(pa);
            if (null != map) {
                Object success = map.get("success");
                if (null != success) {
                    boolean re = (boolean) success;
                    res.setSuccess(re);
                }
            }
        }
        if (null != res && res.isSuccess() && null != one) {
            ReactorVo rVo = new ReactorVo();
            rVo.setPassenger(res.getResult());
            rVo.setDriver(one);
            DriverRebateEvent driverRebateEvent = new DriverRebateEvent(rVo);
            applicationEventMulticaster.multicastEvent(driverRebateEvent);
        }
        entity = new ResponseEntity(res, HttpStatus.OK);
        return entity;
    }
}
